#include "INPUT_CAPTURE_Config.H"

/**
    ******************************************************************************
    * @brief  配置TIM3通道1为输入捕获模式，用于测量外部信号频率
    * @param  无
    * @retval 无
    * @note   输入引脚: 根据CAPTURE_PORT和CAPTURE_PIN宏定义确定
    *         测量范围: 约15Hz~1MHz (受限于定时器分辨率和溢出处理)
    *         系统时钟: 72MHz
    ******************************************************************************
*/
void INPUT_CAPTURE_Config(void)
{
    // 使能GPIO时钟
    RCC_APB2PeriphClockCmd(CAPTURE_CLK, ENABLE);

    // 配置输入引脚为上拉输入模式
    GPIO_InitTypeDef GPIO_InitStructure = {
        .GPIO_Mode  = GPIO_Mode_IPU,      // 上拉输入模式，内部上拉电阻使引脚默认高电平
        .GPIO_Pin   = CAPTURE_PIN,        // 输入捕获引脚
        .GPIO_Speed = GPIO_Speed_50MHz,   // 引脚速度设置（输入模式下实际无效）
    };
    GPIO_Init(CAPTURE_PORT, &GPIO_InitStructure);

    // 使能TIM3时钟（挂载在APB1总线上）
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    // 配置TIM3时基单元 - 决定定时器计数频率
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruce = {
        .TIM_ClockDivision      = TIM_CKD_DIV1,    // 时钟分频因子，不影响输入捕获
        .TIM_CounterMode        = TIM_CounterMode_Up,  // 向上计数模式
        .TIM_Period             = 65536 - 1,       // 自动重载值(ARR)，设置为最大值以延长溢出时间
        .TIM_Prescaler          = 72 - 1,          // 预分频器值(PSC)，将72MHz时钟分频为1MHz
        .TIM_RepetitionCounter  = 0,               // 重复计数器值(高级定时器有效)
    };
    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruce);

    // 配置TIM3通道1为输入捕获模式
    TIM_ICInitTypeDef TIM_ICInitStructure = {
        .TIM_Channel        = TIM_Channel_1,       // 选择通道1
        .TIM_ICFilter       = 0xF,                 // 输入滤波设置，采样4次确认有效边沿
        .TIM_ICPolarity     = TIM_ICPolarity_Rising,  // 上升沿捕获
        .TIM_ICPrescaler    = TIM_ICPSC_DIV1,      // 不分频，每个有效边沿都触发捕获
        .TIM_ICSelection    = TIM_ICSelection_DirectTI,  // 直接映射，TI1信号连接到IC1
    };
    TIM_ICInit(TIMx, &TIM_ICInitStructure);

    // 配置触发源为TI1FP1（通道1的滤波后信号）
    TIM_SelectInputTrigger(TIMx, TIM_TS_TI1FP1);

    // 配置从模式为复位模式
    // 当检测到触发信号时，计数器(TIMx->CNT)复位并开始重新计数
    TIM_SelectSlaveMode(TIMx, TIM_SlaveMode_Reset);

    // 启动TIM3计数器
    TIM_Cmd(TIMx, ENABLE);
}

/**
    ******************************************************************************
    * @brief  获取输入信号的频率
    * @param  无
    * @retval 频率值，单位Hz
    * @note   计算公式: 频率 = 1MHz / (捕获值 + 1)
    *         示例: 若捕获值为999，则频率 = 1000000 / (999 + 1) = 1000Hz
    *         测量限制: 最小频率受限于定时器溢出时间(约15Hz)
    *                  最大频率受限于系统时钟和捕获处理时间(约1MHz)
    ******************************************************************************
*/
u32 INPUT_CAPTURE_GetFreq(void)
{
    // 读取捕获寄存器值并计算频率
    // 由于使用了复位模式，捕获值即为两个相邻上升沿之间的计数值
    // 定时器时钟为1MHz，因此频率计算公式为: 1MHz / (计数值 + 1)
    return (1000000 / (TIM_GetCapture1(TIMx) + 1));
}
